<?php

	class Youtube_Client {

		protected $_googleProfile = array();
		protected $_youtubeClient = false;
		protected $_uploadedVideo = false;
		protected $_videoInfo = false;
		protected $_ffmpegPath = false;
		protected $_watermarkImage = '';
		protected $_videoExtension = '';
		protected $_youtubeCategories = array( 1 => 'Film & Animation', 2 => 'Autos & Vehicles', 10 => 'Music', 15 => 'Pets & Animals', 17 => 'Sports', 18 => 'Short Movies', 19 => 'Travel & Events', 20 => 'Gaming', 21 => 'Videoblogging', 22 => 'People & Blogs', 23 => 'Comedy', 24 => 'Entertainment', 25 => 'News & Politics', 26 => 'Howto & Style', 27 => 'Education', 28 => 'Science & Technology', 29 => 'Nonprofits & Activism', 30 => 'Movies', 31 => 'Anime/Animation', 32 => 'Action/Adventure', 33 => 'Classics', 34 => 'Comedy', 35 => 'Documentary', 36 => 'Drama', 37 => 'Family', 38 => 'Foreign', 39 => 'Horror', 40 => 'Sci-Fi/Fantasy', 41 => 'Thriller', 42 => 'Shorts', 43 => 'Shows', 44 => 'Trailers' );

		function __construct( $googleProfile = array() ) {
			$this->_googleProfile = $googleProfile;
			$this->_watermarkImage = INCLUDE_PATH . 'test_cases' . DIRECTORY_SEPARATOR . 'wmlogo.png';
			$this->_ffmpegPath = PHP_OS == 'Linux' ? '/usr/local/bin/' : 'E:\\ffmpeg\\';
			$httpClient = Zend_Gdata_ClientLogin::getHttpClient(
				$username = 'youtube@qyuki.com',
				$password = 'let me in now',
				$service = 'youtube',
				$client = null,
				$source = 'Test API for Qyuki', // a short string identifying your application
				$loginToken = null,
				$loginCaptcha = null,
				'https://www.google.com/accounts/ClientLogin'
			);
			$developerKey = ''; //YOUTUBE_DEVELOPER_KEY;
			$applicationId = 'Test API for Qyuki';
			$clientId = 'My video upload client - v1';
			$this->_youtubeClient = new Zend_Gdata_YouTube( $httpClient, $applicationId, $clientId, $developerKey );
			$this->_youtubeClient->setMajorProtocolVersion( 2 );
			if( isset( $_SERVER[ 'HTTP_X_FILE_NAME' ] ) &&  isset( $_SERVER[ 'HTTP_X_FILE_SIZE' ] ) && isset( $_SERVER[ 'HTTP_X_FILE_TYPE' ] ) ) {
				$this->_uploadedVideo = tempnam( '/tmp/', 'YTC' ) . '.' . $this->_getExtension();
				$handle = fopen( $this->_uploadedVideo, 'w' );
				fwrite( $handle, file_get_contents( 'php://input' ) );
				fclose( $handle );
				chmod( $this->_uploadedVideo, 0777 );
				$this->_processVideo();
				$this->_videoInfo[ 'type' ] = $_SERVER[ 'HTTP_X_FILE_TYPE' ];
				$this->_videoInfo[ 'name' ] = $_SERVER[ 'HTTP_X_FILE_NAME' ];
			}
		}

		protected function _addWaterMark() {
			$newFileWm = tempnam( '/tmp/', 'YCT' ) . '.' . $this->_getExtension();
			$output = shell_exec( $this->_ffmpegPath . 'ffmpeg -i ' . $this->_uploadedVideo . ' -i ' . $this->_watermarkImage . ' -filter_complex "overlay=10:main_h-overlay_h-10" -strict -2 ' . $newFileWm . ' 2>&1' );
			describe( $output );
			$this->_uploadedVideo = $newFileWm;
		}

		protected function _processVideo() {
			$this->_addWaterMark();
			$output = explode( "\n", shell_exec( $this->_ffmpegPath . 'ffmpeg -i ' . $this->_uploadedVideo . ' 2>&1' ) );
			$started = false;
			$metadataStarted = false;
			$this->_videoInfo = array();
			foreach( $output as $line ) {
				$line = trim( $line );
				if( substr( $line, 0, 8 ) == 'Input #0' ) {
					$started = true;
					continue;
				}
				if( !$started ) {
					continue;
				}
				if( substr( $line, 0, 9 ) == 'Metadata:' && $metadataStarted === false ) {
					$metadataStarted = true;
					continue;
				}
				if( substr( $line, 0, 9 ) == 'Duration:' && $metadataStarted === true ) {
					$metadataStarted = 'completed';
					$line = explode( ', ', $line );
					foreach( $line as $info ) {
						$info = explode( ': ', $info );
						$this->_videoInfo[ $info[ 0 ] ] = $info[ 1 ];
					}
					continue;
				}
				if( substr( $line, 0, 9 ) == 'Stream #0' ) {
					$line = explode( ': ', $line, 3 );
					$this->_videoInfo[ $line[ 1 ] ] = explode( ', ', $line[ 2 ] );
				} else if( count( $line = explode( ':', $line, 2 ) ) == 2  ) {
					if( trim( $line[ 1 ] ) != '' ) {
						$this->_videoInfo[ 'metaData' ][ trim( $line[ 0 ] ) ] = trim( $line[ 1 ] );
					}
				}
			}
		}

		public function showUploadUI( $fieldName = 'videoFile', $caption = 'Select Video File' ) {
			return '<div class="youtubeUploadSection">
				<div class="progresSection">
					<progress value="0" max="100"></progress>
					<span><span>
				</div>
				<div maxsize="' . ini_get( 'upload_max_filesize' ) . '" class="uploadSection" title="Please select a video file less than ' . ini_get( 'upload_max_filesize' ) . '.">
					<input type="button" onclick="var progressBar=this.parentNode.previousElementSibling.getElementsByTagName(\'progress\')[0];progressBar.value=0;progressBar.nextElementSibling.innerHTML = \'\';this.parentNode.getElementsByClassName(\'videoFile\')[0].click();" value="' . $caption . '" />
					<input type="file" class="videoFile" accept="video/*" name="' . $fieldName . '" style="visibility:hidden;width:1px;height:1px" />
				</div>';
		}

		private function _getExtension() {
			$extension = explode( '.', $_SERVER[ 'HTTP_X_FILE_NAME' ] );
			return end( $extension );
		}

		private function _getSlug() {
			$title = strtolower( strip_tags( $this->_videoInfo[ 'name' ] ) );
			$extension = explode( '.', $title );
			$extension = end( $extension );
			$title = substr( $title, 0, strlen( $title ) - strlen( $extension ) - 1 );
			foreach( array( '/&.+?;/', '/[^A-Za-z0-9 _-]/', '/\s+/', '|-+|' ) as $regex ) {
				$title = preg_replace( $regex, '-', $title );
			}
			$this->_videoExtension = $extension;
			return substr( trim( $title, '-' ), -50 ) . '.' . $extension;
		}

		public function upload( $title, $description, $category, $tags, $location = '37.0 -122.0' ) {
			$newVideoEntry = new Zend_Gdata_YouTube_VideoEntry();
			$filesource = $this->_youtubeClient->newMediaFileSource( $this->_uploadedVideo );
			$filesource->setContentType( $this->_videoInfo[ 'type' ] );
			$filesource->setSlug( $this->_getSlug() );
			$newVideoEntry->setMediaSource( $filesource );
			$newVideoEntry->setVideoTitle( $title );
			$newVideoEntry->setVideoDescription( $description );
			$newVideoEntry->setVideoCategory( $category );
			$newVideoEntry->SetVideoTags( $tags );
			$newVideoEntry->setVideoDeveloperTags( array( 'qyuki test video', 'by rashid mohamad' ) );
			$this->_youtubeClient->registerPackage( 'Zend_Gdata_Geo' );
			$this->_youtubeClient->registerPackage( 'Zend_Gdata_Geo_Extension' );
			$where = $this->_youtubeClient->newGeoRssWhere();
			$position = $this->_youtubeClient->newGmlPos( $location );
			$where->point = $this->_youtubeClient->newGmlPoint( $position );
			$newVideoEntry->setWhere( $where );
			$uploadUrl = 'http://uploads.gdata.youtube.com/feeds/api/users/default/uploads';
			try {
				$newEntry = $this->_youtubeClient->insertEntry( $newVideoEntry, $uploadUrl, 'Zend_Gdata_YouTube_VideoEntry' );
				return $newEntry;
			} catch( Zend_Gdata_App_HttpException $httpException ) {
				describe( $httpException->getMessage(), $httpException->getTraceAsString() );
				echo $httpException->getRawResponseBody();
			} catch( Zend_Gdata_App_Exception $ex ) {
				describe( $ex->getMessage(), $ex->getTraceAsString() );
				echo $ex->getMessage();
			}
			return false;
		}

		public function __call( $functionName, $argumentsList ) {
			$varName = '_' . lcfirst( str_replace( 'get', '', $functionName ) );
			if( isset( $this->$varName ) ) {
				return $this->$varName;
			} else {
				throw new Exception( "Call to undefined function $functionName!" );
			}
		}

		public function getReport( $startDate = null, $endDate = null, $metrics = 'views,dislikes,likes', $ids = '' ) {
			//describe( $this->_googleProfile );
			if( $startDate === null ) {
				$startDate = date( 'Y-m-d', strtotime( '-1 month' ) );
			}
			if( $endDate === null ) {
				$endDate = date( 'Y-m-d' );
			}

			$reportUrl = 'https://www.googleapis.com/youtube/analytics/v1/reports?access_token=' . urlencode( $this->_googleProfile[ 'access_token' ][ 'access_token' ] ) . '&start-date=' . $startDate . '&end-date=' . $endDate . '&metrics=' . $metrics . '&ids=' . urlencode( 'channel==' . $this->_googleProfile[ 'channels' ][ 'items' ][ 0 ][ 'id' ] );
			describe( file_get_contents( $reportUrl ), true );
		}
	}